package common.util;

import java.util.*;

public class ArrayUtil {

    /**
     * 数组交换
     *
     * @param arr
     * @param i
     * @param j
     */
    public static void swap(int[] arr, int i, int j) {
        try {
            if (i == j) {
                return;
            }
            arr[i] = arr[i] ^ arr[j];
            arr[j] = arr[i] ^ arr[j];
            arr[i] = arr[i] ^ arr[j];
        } catch (Exception e) {
            throw e;
        }

    }

    /**
     * 随机长度数组生成
     *
     * @param maxLength
     * @param maxNumber
     * @return
     */
    public static int[] instantRandom(int maxLength, int maxNumber) {
        Random random = new Random();
        int length = random.nextInt(maxLength - 1) + 1;
        int[] arr = new int[length];
        for (int i = 0; i < length; i++) {
            arr[i] = random.nextInt(maxNumber - 1) + 1;
        }
        return arr;
    }

    /**
     * 随机长度数组生成
     *
     * @param maxLength
     * @param maxNumber
     * @return
     */
    public static int[] instantDistinct(int maxLength, int maxNumber) {
        Random random = new Random();
        HashSet<Integer> set = new HashSet<>();
        int[] arr = new int[maxLength];
        for (int i = 0; i < maxLength; i++) {
            int num = random.nextInt(maxNumber - 1) + 1;
            while (set.contains(num)) {
                num = random.nextInt(maxNumber - 1) + 1;
            }
            set.add(num);
            arr[i] = num;
        }
        return arr;
    }

    /**
     * 随机长度数组生成（含负数）
     *
     * @param maxLength
     * @param maxNumber
     * @return
     */
    public static int[] instantDistinctNegative(int maxLength, int maxNumber) {
        Random random = new Random();
        HashSet<Integer> set = new HashSet<>();
        int[] arr = new int[maxLength];
        for (int i = 0; i < maxLength; i++) {
            int num = random.nextInt(maxNumber * 2 - 1) - maxNumber;
            while (set.contains(num)) {
                num = random.nextInt(maxNumber * 2 - 1) - maxNumber;
            }
            set.add(num);
            arr[i] = num;
        }
        return arr;
    }

    /**
     * 随机长度数组生成
     *
     * @param maxLength
     * @param maxNumber
     * @return
     */
    public static int[] instant(int maxLength, int maxNumber) {
        Random random = new Random();
        int[] arr = new int[maxLength];
        for (int i = 0; i < maxLength; i++) {
            arr[i] = random.nextInt(maxNumber - 1) + 1;
        }
        return arr;
    }


    /**
     * 生成包含若干奇数和偶数的数字
     * <p>
     * odd 奇数个数
     *
     * @return 目标集合
     * 第一位 数组
     * 第二位 奇数数组
     */
    public static List<int[]> instantOddAndEven(int odd) {
        Random random = new Random();
        List<int[]> result = new ArrayList<>();
        int[] odds = new int[odd];
        int[] ints = ArrayUtil.instantDistinctNegative(100, 1000);
        while (odd >= ints.length) {
            ints = ArrayUtil.instantDistinctNegative(100, 1000);
        }
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < ints.length; i++) {
            int count;
            if (i > odd - 1) {
                count = random.nextInt(10) * 2;
            } else {
                odds[i] = ints[i];
                count = random.nextInt(10) * 2 + 1;
            }
            for (int j = 0; j < count; j++) {
                list.add(ints[i]);
            }
        }
        Collections.shuffle(list);
        int[] arr = new int[list.size()];
        for (int i = 0; i < list.size(); i++) {
            arr[i] = list.get(i);
        }
        result.add(arr);//数组
        result.add(odds);//基数数字
        return result;
    }


    /**
     * 一个数组中有一种数出现K次，其他数都出现了M次，
     *
     * @return 目标集合
     * 第一位 数组
     * 第二位 K,M,KNum
     * @return
     */
    public static List<int[]> instantKM() {
        List<int[]> result = new ArrayList<>();

        int[] ints = ArrayUtil.instantDistinctNegative(100, 1000);
        int K = randomInt(1, 100);
        int M = randomInt(K + 1, K + 100);
        List<Integer> list = new ArrayList<>();
        for (int i = 0; i < ints.length; i++) {
            int count;
            if (i == 0) {
                count = K;
            } else {
                count = M;
            }
            for (int j = 0; j < count; j++) {
                list.add(ints[i]);
            }
        }

        Collections.shuffle(list);
        int[] arr = new int[list.size()];
        for (int i = 0; i < list.size(); i++) {
            arr[i] = list.get(i);
        }
        int[] km = new int[3];
        km[0] = K;
        km[1] = M;
        km[2] = ints[0];

        result.add(arr);
        result.add(km);

//        System.out.println(Arrays.toString(km));
//        System.out.println(Arrays.toString(arr));

        return result;
    }


    /**
     * 数组复制
     *
     * @param arr
     * @return
     */
    public static int[] copy(int[] arr) {
        int[] arrCopy = new int[arr.length];
        for (int i = 0; i < arr.length; i++) {
            arrCopy[i] = arr[i];
        }
        return arrCopy;
    }

    /**
     * 数组比较
     *
     * @param arr1
     * @param arr2
     * @return
     */
    public static boolean compare(int[] arr1, int[] arr2) {
        if (arr1.length != arr2.length) {
            return false;
        }
        for (int i = 0; i < arr1.length; i++) {
            if (arr1[i] != arr2[i]) {
                return false;
            }
        }
        return true;
    }

    /*

     * 生成[min, max]之间的随机整数
     * @param min 最小整数
     * @param max 最大整数
     */
    public static int randomInt(int min, int max) {
        return new Random().nextInt(max) % (max - min + 1) + min;
    }

    public static void main(String[] args) {
        int[] arr = instantDistinct(10, 20);
        System.out.println(Arrays.toString(arr));
    }

}
